﻿#region Copyright (c) 2011, thinktecture (http://www.thinktecture.com)

/*
   thinktecture.UIAnnotations was developed by Jörg Neumann.
   Copyright (c) 2011, thinktecture (http://www.thinktecture.com).
   All rights reserved, comes as-is and without any warranty. Use of this
   source file is governed by the license which is contained in LICENSE.TXT 
   in the distribution.
*/

#endregion

using System;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Media;

namespace Thinktecture.UIAnnotations
{
    public class RequiredFieldAdorner : Adorner
    {
        private bool _isRequired;
        private ExtensionImageAlignment _alignment;
        private FrameworkElement _child;

        public RequiredFieldAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            this.Focusable = false;
            _alignment = ExtensionImageAlignment.Right;

            this.CreateChild();
        }

        public RequiredFieldAdorner(UIElement adornedElement, 
            bool isRequired,
            ExtensionImageAlignment alignment)
            : base(adornedElement)
        {
            this.Focusable = false;
            _isRequired = isRequired;
            _alignment = alignment;
            if (_isRequired)
            {
                this.CreateChild();
            }
        }

        private void CreateChild()
        {
            this.RemoveChild();
            BitmapImage icon = new BitmapImage();
            icon.BeginInit();
            Uri imageUri = new Uri("pack://application:,,,/Thinktecture.UIAnnotations;component/Images/Required.png");
            if (this.Alignment == ExtensionImageAlignment.Left)
                imageUri = new Uri("pack://application:,,,/Thinktecture.UIAnnotations;component/Images/RequiredFront.png");
            icon.UriSource = imageUri;
            icon.EndInit();
            _child = new Image() { Source = icon, Stretch=Stretch.None, ToolTip="Required Field" };
            this.AddVisualChild(_child);
            this.InvalidateMeasure();
        }

        private void RemoveChild()
        {
            if (_child != null)
            {
                this.RemoveVisualChild(_child);
                this.InvalidateMeasure();
                _child = null;
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
            if (_child == null)
                return finalSize;
            
            Point pos = new Point();
            if (_alignment == ExtensionImageAlignment.Left)
            {
                pos.X -= _child.DesiredSize.Width + 3;
                pos.Y = (adornedElement.ActualHeight - _child.DesiredSize.Height) / 2;
            }
            else
            {
                pos.X = adornedElement.ActualWidth + 3;
                pos.Y = (adornedElement.ActualHeight - _child.DesiredSize.Height) / 2;
            }

            _child.Arrange(new Rect(pos, _child.DesiredSize));
            
            return base.ArrangeOverride(finalSize);
        }

        protected override int VisualChildrenCount
        {
            get { return _child == null ? 0 : 1; }
        }

        protected override Visual GetVisualChild(int index)
        {
            if (index == 0 && _child != null)
            {
                return _child;
            }
            return base.GetVisualChild(index);
        }

        public bool IsRequired
        {
            get { return _isRequired; }
            set
            {
                _isRequired = value;
                if (_isRequired)
                    this.CreateChild();
                else
                    this.RemoveChild();
            }
        }

        public ExtensionImageAlignment Alignment
        {
            get { return _alignment; }
            set { _alignment = value; this.CreateChild(); }
        }
    }
}
